(function () {
	var ns = ij.pkg('core').namespaceString;
	ij.core.AnimationInstruction = ij.core.Observable.extend({
		init: function (config) {
			return this._super(ij.apply({
				classname: ns+'.AnimationInstruction',
				animation: null,
				running: false,
				paused: false
			}, config));
		},
		start: function () {
			this.running = true;
			this.paused = false;
			this.dispatchEvent('start');
			
			return this;
		},
		stop: function () {
			this.running = false;
			this.paused = false;
			this.dispatchEvent('stop');
			
			return this;
		},
		pause: function () {
			if (this.running && !this.paused) {
				this.paused = true;
				this.dispatchEvent('pause');
			}
			
			return this;
		},
		resume: function () {
			if (this.running && this.paused) {
				this.paused = false;
				this.dispatchEvent('resume');
			}
			
			return this;
		},
		step: function () {
			if (this.running && !this.paused) {
				this.dispatchEvent('step');
			}
		}
	});
	
	ij.core.AnimationInstructionLinearFrame = ij.core.AnimationInstruction.extend({
		init: function (config) {
			return this._super(ij.apply({
				classname: ns+'.AnimationInstructionLinearFrame',
				frames: 0,
				startX: 0,
				startY: 0,
				speed: 1,
				loop: 1,
				currentLoop: 0,
				currentFrame: 0,
				_renderCount: 0
			}, config));
		},
		start: function () {
			if (this._interval) {
				this.stop();
			}
			this.currentLoop = 0;
			this.currentFrame = 0;
			
			return this._super();
		},
		_intervalCallback: function () {
			this._renderCount++;
			if (this._renderCount >= this.speed) {
				this._renderCount = 0;
				if (this.currentFrame == this.frames) {
					this.currentLoop++;
					this.currentFrame = 0;
					if (this.currentLoop == this.loop) {
						this.stop();
					}
				}
				obj = this.animation.animatedObject;
				if (this.currentFrame == 0) {
					obj.moveSpriteTo(this.startX, this.startY);
				} else {
					obj.moveSpriteBy(obj.width);
				}
				this.currentFrame++;
			}
		},
		step: function () {
			if (this.running && !this.paused) {
				this._intervalCallback();
			}
			this._super();
			
			return this;
		}
	});
	
	ij.core.AnimationInstructionCSSTransformation = ij.core.AnimationInstruction.extend({
		init: function (config) {
			this._super(ij.apply({
				classname: ns+'.AnimationInstructionCSSTransformation',
				transformation: {},
				transition: {},
				loop: 1,
				currentLoop: 0
			}, config));
			this.animation.animatedObject.bind('webkitTransitionEnd', function () {
				this.loopComplete();
			}, this);
		},
		start: function () {
			var obj = this.animation.animatedObject;
			obj.setTransition(this.transition);
			obj.performTransformation(this.transformation);
			
			return this._super();
		},
		loopComplete: function () {
			this.currentLoop++;
			if (this.currentLoop == this.loop) {
				this.complete();
			} else {
				this.start();
			}
		},
		stop: function () {
			this.currentLoop = 0;
			return this._super();
		},
		pause: function () {
			return this._super();
		},
		resume: function () {
			return this._super();
		}
	});
})();
